/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_NODE_INTERNAL_H
#define IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_NODE_INTERNAL_H

#include "imageknife_node.h"
#include "arkui_node.h"
#include "request/imageknife_request_internal.h"
#include "image_data_cache_internal.h"

namespace ImageKnifeC {

class ImageKnifeNodeInternal : public ImageKnifeNode, public ArkUINode {
public:
    enum NodeState {
        Available,
        Cleared
    };

    ImageKnifeNodeInternal(std::string componentId, std::shared_ptr<ImageKnifeOption> option, ArkUI_NodeHandle handle)
        : ArkUINode(handle), componentId_(componentId)
    {
        imageKnifeRequest_ = std::make_shared<ImageKnifeRequestInternal>(componentId_, option, GetNodeVersion());
        SetBorder();

        GetNodeAPI()->setUserData(handle, this);
        GetNodeAPI()->addNodeEventReceiver(handle, OnNodeEvent);
//         GetNodeAPI()->registerNodeEvent(handle, NODE_EVENT_ON_AREA_CHANGE, 0, nullptr);
    }

    ~ImageKnifeNodeInternal() override
    {
//         GetNodeAPI()->unregisterNodeEvent(handle, NODE_EVENT_ON_AREA_CHANGE);
        GetNodeAPI()->removeNodeEventReceiver(handle, OnNodeEvent);
        GetNodeAPI()->disposeNode(handle);
    }

    virtual bool IsAnimator() const = 0;

    // 必需在主线程中运行
    virtual bool Display(std::shared_ptr<ImageDataCacheInternal> data, bool isPlaceSrc) = 0;

    virtual void FitImage(int fitEnum)
    {
    }

    virtual void UpdateAnimatorOption(std::shared_ptr<AnimatorOption> option)
    {
    }

    void UpdateImageKnifeRequest(std::shared_ptr<ImageKnifeOption> option);

    void SyncLoad(bool syncLoad) override;

    void Reuse()
    {
        componentVersion_++;
        nodeState_ = Available;
    }

    void Clear()
    {
        nodeState_ = Cleared;
        RemoveDisplayedImage();
    }

    std::shared_ptr<ImageKnifeRequest> GetImageKnifeRequest() const override
    {
        return imageKnifeRequest_;
    }

    int GetNodeVersion() const
    {
        return componentVersion_;
    }

    ArkUI_NodeHandle GetHandle() const override
    {
        return handle;
    }

    NodeState GetNodeState() const
    {
        return nodeState_;
    }

    float GetWidth() const
    {
        return width_;
    }

    float GetHeight() const
    {
        return height_;
    }

    void SetWidth(float width) override;

    void SetHeight(float height) override;

    void SetPercentWidth(float width) override;

    void SetPercentHeight(float height) override;
private:
    float width_ = 0;
    float height_ = 0;

    int componentVersion_ = 0;
    NodeState nodeState_ = Available;

    ArkUI_NumberValue borderWidth_[4];
    ArkUI_NumberValue borderRadius_[4];
    ArkUI_NumberValue borderColor_[4];
    ArkUI_NumberValue borderStyle_[4];

    std::string componentId_;
    // 保持request生命周期
    std::shared_ptr<ImageKnifeRequest> imageKnifeRequest_;

    virtual void RemoveDisplayedImage() = 0;

    static void OnNodeEvent(ArkUI_NodeEvent *event);

    void OnAreaChange(ArkUI_NodeEvent *event);

    virtual void OnDerivedNodeEvent(ArkUI_NodeEvent *event)
    {
    }

    virtual void UpdateDerivedNodeEvent(std::shared_ptr<ImageKnifeOption> option)
    {
    }
    
    void SetBorder();
};

} // end of namespace

#endif // IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_NODE_INTERNAL_H